package com.lyun.controller;

import com.aliyuncs.exceptions.ClientException;
import com.lyun.bo.FriendsBo;
import com.lyun.bo.GetBlackListBo;
import com.lyun.common.*;
import com.lyun.dto.*;
import com.lyun.pojo.Settings;
import com.lyun.pojo.User;
import com.lyun.service.*;
import com.lyun.vo.*;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Objects;

@RestController
@RequestMapping("/users")
@CrossOrigin
@Slf4j
public class UsersController {

    @Resource
    private UserService userService;

    @Resource
    private SendSms sendSms;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private OssTemplate ossTemplate;

    @Resource
    private GetTags getTags;

    @Resource
    private SettingService settingService;

    @DubboReference
    private BlacklistService blacklistService;

    @DubboReference
    private EachLoveService eachLoveService;

    @DubboReference
    private VisitorService visitorService;

    @DubboReference
    private LoveValueService loveValueService;

    /**
     *
     * @param token
     * @return
     * @throws ParseException
     */
    @GetMapping
    public UsersDataVo getUserData(@RequestHeader(name = "Authorization", required = false) String token) throws ParseException {

        Claims claims = JwtUtils.getClaims(token);
        String phone = (String) claims.get("phone");
        User user = userService.getByPhone(phone);

        UsersDataVo usersDataVo = new UsersDataVo();
        BeanUtils.copyProperties(user, usersDataVo);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(user.getBirthday());
        usersDataVo.setBirthday(format);
        usersDataVo.setAge(Integer.toString(GetAge.getAgeForBirthday(format)));

        usersDataVo.setAvatar(user.getHeader());
        log.info("usersDataVo = " + usersDataVo);

        return usersDataVo;
    }

    /**
     * 修改手机号 发送验证码
     *
     * @param token
     * @throws ClientException
     */
    @PostMapping("/phone/sendVerificationCode")
    public void sendVerificationCode(@RequestHeader(name = "Authorization", required = false) String token) throws ClientException {
        Claims claims = JwtUtils.getClaims(token);
        String phone = (String) claims.get("phone");
        userService.sendVerificationCode(phone);
    }

    @PostMapping("/phone/checkVerificationCode")
    public CheckVerificationCodeVo checkVerificationCode(@RequestHeader(name = "Authorization", required = false) String token, @RequestBody CheckVerificationCodeDto dto) throws ClientException {
        Claims claims = JwtUtils.getClaims(token);
        String phone = (String) claims.get("phone");
        String code = redisTemplate.opsForValue().get(phone);
        CheckVerificationCodeVo vo = new CheckVerificationCodeVo();

        if (code == null || !code.equals(dto.getVerificationCode())) {
            vo.setVerification(false);
            return vo;
        }
        vo.setVerification(true);
        return vo;
    }

    @PostMapping("/phone")
    public void updatePhone(@RequestHeader(name = "Authorization") String token, @RequestBody UpdatePhoneDto dto) {
        Claims claims = JwtUtils.getClaims(token);
        long id = ((Integer) claims.get("id")).longValue();

        String newPhone = dto.getPhone();
        if (!StringUtils.hasText(newPhone)) {
            throw new MyBusinessException("请输入手机号");
        }

        User userByPhone = userService.getByPhone(newPhone);
        if (userByPhone != null) {
            throw new MyBusinessException("该手机号已绑定用户");
        }

        User user = new User();
        user.setPhone(newPhone);
        user.setId(id);
        userService.updateById(user);
    }

    @PostMapping("/header")
    public void updateHeader(@RequestBody MultipartFile headPhoto) throws IOException {
        String upload = ossTemplate.upload(headPhoto);

        if (Objects.isNull(upload) || "".equals(upload)) {
            return;
        }

        Long id = BaseContext.getCurrentId();

        User user = new User();
        user.setHeader(upload);
        user.setId(id);
        userService.updateData(user);

    }

    @PutMapping
    public User updateData(@RequestHeader(name = "Authorization") String token, @RequestBody UpdateUsersDataDto dto) throws ParseException {
        Claims claims = JwtUtils.getClaims(token);
        Long id = ((Integer) claims.get("id")).longValue();
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        user.setId(id);
//        System.out.println(dto.getBirthday());
        if (dto.getBirthday() != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            int age = GetAge.getAgeForBirthday(sdf.format(dto.getBirthday()));
            user.setAge(age);
        }
        user.setTags(getTags.getTags(user).toString().replace("[", "").replace("]", "").trim());

//        System.out.println("updateData...user = " + user);
        return userService.updateData(user) ? user : null;
    }

    @GetMapping("/settings")
    public Settings settings(@RequestHeader(name = "Authorization") String token) {
        Claims claims = JwtUtils.getClaims(token);
        String phone = (String) claims.get("phone");
        return settingService.getByPhone(phone);
    }

    /**
     * 设置陌生人问题
     *
     * @param token
     * @param dto
     */
    @PostMapping("/questions")
    public R<String> questions(@RequestHeader(name = "Authorization") String token, @RequestBody QuestionsDto dto) {
        Claims claims = JwtUtils.getClaims(token);
        Long userId = ((Integer) claims.get("id")).longValue();
        Settings settings = new Settings();
        settings.setUserId(userId);
        settings.setStrangerQuestion(dto.getContent());

        return settingService.updateQuestions(settings) ? R.success("修改成功") : R.error("修改失败");
    }

    /**
     * 修改通知设置
     *
     * @return
     */
    @PostMapping("/notifications/setting")
    public R<String> updateNotification(@RequestHeader(name = "Authorization") String token, @RequestBody NotificationsDto dto) {
        Claims claims = JwtUtils.getClaims(token);
        String phone = (String) claims.get("phone");
        Settings settings = new Settings();
        BeanUtils.copyProperties(dto, settings);
        settings.setPhone(phone);
        return settingService.changeSettings(settings) ? R.success("修改成功") : R.error("修改失败");
    }

    /**
     * 查询黑名单列表
     *
     * @param page     页码
     * @param pageSize 每页显示条数
     * @return
     */
    @GetMapping("/blacklist")
    public PageVO<BlacklistVO> blacklistVoPage(@RequestParam(value = "page", required = false) Integer page,
                                               @RequestParam(value = "pageSize", required = false) Integer pageSize) {

        if (pageSize == null) {
            pageSize = 1;
        }

        Long userId = BaseContext.getCurrentId();
        GetBlackListBo bo = new GetBlackListBo();
        bo.setId(userId);
        bo.setPage(page);
        bo.setPageSize(pageSize);
        return blacklistService.getPageList(bo);
    }

    @DeleteMapping("/blacklist/{uid}")
    public R<String> deleteBlacklist(@PathVariable("uid") String uid) {
        long blacklistId = Long.parseLong(uid);
        return blacklistService.deleteById(blacklistId) ? R.success("取消黑名单成功") : R.error("取消黑名单失败");
    }

    /**
     * 用户端 获取喜欢、粉丝数
     * @param token
     * @return
     */
    @GetMapping("/counts")
    public LoveCountVo eachLoveCount(@RequestHeader(name = "Authorization") String token) {
        Claims claims = JwtUtils.getClaims(token);
        Long userId = ((Integer) claims.get("id")).longValue();

        //todo 先用standby
        return userService.getCountsStandby(userId);
    }

    /**
     * 1 互相关注，2 我关注，3 粉丝，4 谁看过我
     *
     * @param token
     * @param type
     * @param page
     * @param pagesize
     * @param nickname
     * @return
     */
    @GetMapping("/friends/{type}")
    public PageVO<FriendsVo> friendsShow(@RequestHeader(name = "Authorization") String token,
                                         @PathVariable("type") Integer type,
                                         @RequestParam Integer page,
                                         @RequestParam Integer pagesize,
                                         @RequestParam(required = false) String nickname) {
        Claims claims = JwtUtils.getClaims(token);
        Long id = ((Integer) claims.get("id")).longValue();
        FriendsBo bo = new FriendsBo();
        bo.setUserId(id);
        bo.setType(type);
        bo.setPage(page);
        bo.setPageSize(pagesize);
        if (StringUtils.hasText(nickname)) {
            bo.setNickname(nickname);
        }
        return userService.getFriendsVoList(bo);
    }

    @GetMapping("/{uid}/alreadyLove")
    public boolean getAlreadyLove(@RequestHeader(name = "Authorization") String token,
                                  @PathVariable Long uid) {
        Claims claims = JwtUtils.getClaims(token);
        long id = ((Integer) claims.get("id")).longValue();

        return eachLoveService.getAlreadyLoveByUserIdAndToId(id, uid);
    }
}
